package com.zdp.rabbitmq.consumer;

import com.alibaba.fastjson.JSONObject;
import com.rabbitmq.client.Channel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.Arrays;

/**
 * @author sesshomaru
 * @date 2019/11/27 21:51
 */
@Component
public class OrderDlxConsumer {
    private static final Logger log = LoggerFactory.getLogger(OrderDlxConsumer.class);

    /**
     * 死信消费
     * 1.消息超时
     * 2.消息被nck 并且 不重回队列
     * 3.消息被nck 并且 重回队列 但 消息设置了有效期 消息的有效期到也会进入这里
     * 4.队列超长
     */
    @RabbitListener(queues = "order_dlx")
    @RabbitHandler
    public void orderDlx(JSONObject jsonObject, Message message, Channel channel) throws IOException {
        String msg = jsonObject.getString("msg");
        log.info(msg+"已失效!~");
        long deliveryTag = message.getMessageProperties().getDeliveryTag();
        channel.basicAck(deliveryTag,true);
    }

    @RabbitListener(queues = "order_queue")
    @RabbitHandler
    public void order(JSONObject jsonObject, Message message, Channel channel) throws IOException{
        //应该将业务方法 和 解析的方法放入try 里面 catch中方 nck
        String msg = jsonObject.getString("msg");
        long deliveryTag = message.getMessageProperties().getDeliveryTag();
        String substring = msg.substring(0,2);
        //String[] array = {"17","12","13","14","15","16"};
        //通过二分查找来判断
        //int i = Arrays.binarySearch(array, substring);

        try {
            Integer integer = Integer.valueOf(substring);
            //这里最好是在外部比较好后确认是否需要 放入死信 否则第一条会被正常消费(bug)
            boolean b = integer >= 10;
            if(b){
                log.info(msg+"下单成功!~");
                 //正常消费不会进入死信
                channel.basicAck(deliveryTag,true);
            }else {
                //设置不ack 且不重回队列 那么就进入死信
                log.error(msg+"下单失败!~");
                channel.basicNack(deliveryTag,false,false);
            }
        } catch (Exception e) {
            log.error(msg+"下单失败!~");
            channel.basicNack(deliveryTag,false,true);
        }
    }
}
